import cv2
import tkinter as tk
from PIL import Image, ImageTk
import numpy as np
import os
def face_gui():
    root = tk.Tk()
    root.title("人脸识别系统软件")

    camera_port = tk.StringVar()
    camera_port.set("2")  # 设置默认相机端口为0

    resolution = tk.StringVar()
    resolution.set("720p")  # 设置默认分辨率为480p

    haarcascade = tk.StringVar()
    haarcascade.set("models/haarcascade_frontalface_default.xml")  # 设置默认haarcascade模型

    current_image = None

    # 创建图像显示区域
    canvas = tk.Canvas(root,height=300,width=800)
    canvas.grid(row=5, column=0, rowspan=1, columnspan=6)
    color_label = tk.Label(canvas)
    depth_label = tk.Label(canvas)
    canvas.create_window(200, 150, window=color_label)
    canvas.create_window(600, 150, window=depth_label)
    # color_label = tk.Label(root)
    # color_label.grid(row=5, column=0,columnspan=3)

    # depth_label = tk.Label(root)
    # depth_label.grid(row=5, column=4,columnspan=3)


    def open_camera():
        # 从相机读取图像
        global cap
        camera_ports = camera_port.get()
        if camera_ports == "":
            camera_ports = 0  # 如果相机端口为空字符串，则设置为默认端口0
        else:
            camera_ports = int(camera_ports)
        cap = cv2.VideoCapture(camera_ports)

        resolutions = resolution.get()
        match resolutions:
            case "720p":
                cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
                cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 768)
            case "480p":
                cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
                cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
            case "360p":
                cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
                cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
        ret, frame = cap.read()
        try:
            while ret:
                ret, frame = cap.read()
                # 在图像上进行人脸检测
                gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
                cascade = cv2.CascadeClassifier(haarcascade.get())
                faces = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

                current_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                pil_current_image = Image.fromarray(current_image)
                # 在图像上绘制人脸框并显示
                for (x, y, w, h) in faces:
                    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

                # 将OpenCV图像转换为PIL图像
                face_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                pil_face_image = Image.fromarray(face_image)

                # 将PIL图像转换为Tkinter图像
                tk_current_image = ImageTk.PhotoImage(pil_current_image.resize((400, 300)))
                tk_face_image = ImageTk.PhotoImage(pil_face_image.resize((400, 300)))

                # 更新图像显示
                color_label.config(image=tk_current_image)
                depth_label.config(image=tk_face_image)

                # 保持图像显示的引用，防止被垃圾回收
                color_label.image = pil_current_image
                depth_label.image = pil_face_image

                # 每隔100毫秒更新图像显示
                root.update()
        finally:
            cap.release()

    # 创建保存图像函数
    def save_image(color_image):
        # 创建data文件夹（如果不存在）
        if not os.path.exists("data"):
            os.makedirs("data")

        # 获取data文件夹下已保存图像的数量
        # num_files = len(os.listdir("data"))

            # 获取data文件夹下最大的序号
        num_files = 0
        for file_name in os.listdir("./data"):
            if file_name.endswith(".png"):
                index = int(file_name.split(".")[0])
                num_files = max(num_files, index)

        # 保存彩色图为PNG格式
        color_image_path = "data/{:04d}.png".format(num_files + 1)
        color_image.save(color_image_path)
        print(f"Color image saved as {color_image_path}")


    def save_button_callback():
        # 获取当前显示的彩色图和深度图
        color_image = color_label.image
        # 保存当前图像
        if color_image is not None:
            save_image(color_image)
        else:
            print("No image to save")

    def close_camera():
        # camera_static = 1
        cap.release()

    # 创建退出按键的回调函数
    def image_button_callback():
        # 停止相机并关闭窗口
        # pipeline.stop()
        root.destroy()

    # 创建相机端口选择菜单
    camera_label = tk.Label(root, text="相机  端口:")
    camera_label.grid(row=1, column=1)

    camera_menu = tk.OptionMenu(root, camera_port, "0", "1", "2")
    camera_menu.configure(width=100)
    camera_menu.grid(row=1, column=3, columnspan=2)

    # 创建分辨率选择菜单
    resolution_label = tk.Label(root, text="图像分辨率:")
    resolution_label.grid(row=2, column=1)

    resolution_menu = tk.OptionMenu(root, resolution, "720p", "480p", "360p")
    resolution_menu.configure(width=100)
    resolution_menu.grid(row=2, column=3, columnspan=2)

    # 创建haarcascade模型选择菜单
    haarcascade_label = tk.Label(root, text="Haar 模型:")
    haarcascade_label.grid(row=3, column=1)

    haarcascade_menu = tk.OptionMenu(root, haarcascade, "models/haarcascade_frontalface_alt.xml", "models/haarcascade_frontalface_alt2.xml", "models/haarcascade_frontalface_default.xml")
    haarcascade_menu.configure(width=100)
    haarcascade_menu.grid(row=3, column=3, columnspan=2)

   # 创建打开相机按钮
    open_button = tk.Button(root, text="打开相机", command=open_camera, bg='green',fg='yellow')
    open_button.grid(row=4, column=1)

    # 创建关闭相机按钮
    close_button = tk.Button(root, text="关闭相机", command=close_camera, bg='red',fg='yellow')
    close_button.grid(row=4, column=3)

    # 创建保存图像按钮
    save_button = tk.Button(root, text="保存图像", command=save_button_callback, bg='blue',fg='yellow')
    save_button.grid(row=4, column=5)

    # 创建退出图像按钮
    image_Exit_button = tk.Button(root, text="退出", command=image_button_callback, bg='red',fg='yellow')
    image_Exit_button.grid(row=7, column=6)

    la2=tk.Label(root,text='原始图像')
    la2.grid(row=6,column=1) # 0行0列

    la2=tk.Label(root,text='识别图像')
    la2.grid(row=6,column=5) # 0行0列

    root.mainloop()

if __name__ == '__main__':
    face_gui()
